﻿
#region Using directives

using System;
using System.Collections;
using System.Collections.Specialized;


using System.Web.Configuration;
using System.Data;
using System.Data.Common;
using System.Configuration.Provider;

using Microsoft.Practices.EnterpriseLibrary.Data;
using Microsoft.Practices.EnterpriseLibrary.Data.Sql;

using SaleManagement.Domains;
using SaleManagement.Data;
using SaleManagement.Data.Bases;

#endregion

namespace SaleManagement.Data.SqlClient
{
	/// <summary>
	/// This class is the Sql implementation of the NetTiersProvider.
	/// </summary>
	public sealed class SqlNetTiersProvider : SaleManagement.Data.Bases.NetTiersProvider
	{
		private static object syncRoot = new Object();
		private string _applicationName;
        private string _connectionString;
        private bool _useStoredProcedure;
        string _providerInvariantName;
		
		/// <summary>
		/// Initializes a new instance of the <see cref="SqlNetTiersProvider"/> class.
		///</summary>
		public SqlNetTiersProvider()
		{	
		}		
		
		/// <summary>
        /// Initializes the provider.
        /// </summary>
        /// <param name="name">The friendly name of the provider.</param>
        /// <param name="config">A collection of the name/value pairs representing the provider-specific attributes specified in the configuration for this provider.</param>
        /// <exception cref="T:System.ArgumentNullException">The name of the provider is null.</exception>
        /// <exception cref="T:System.InvalidOperationException">An attempt is made to call <see cref="M:System.Configuration.Provider.ProviderBase.Initialize(System.String,System.Collections.Specialized.NameValueCollection)"></see> on a provider after the provider has already been initialized.</exception>
        /// <exception cref="T:System.ArgumentException">The name of the provider has a length of zero.</exception>
		public override void Initialize(string name, NameValueCollection config)
        {
            // Verify that config isn't null
            if (config == null)
            {
                throw new ArgumentNullException("config");
            }

            // Assign the provider a default name if it doesn't have one
            if (String.IsNullOrEmpty(name))
            {
                name = "SqlNetTiersProvider";
            }

            // Add a default "description" attribute to config if the
            // attribute doesn't exist or is empty
            if (string.IsNullOrEmpty(config["description"]))
            {
                config.Remove("description");
                config.Add("description", "NetTiers Sql provider");
            }

            // Call the base class's Initialize method
            base.Initialize(name, config);

            // Initialize _applicationName
            _applicationName = config["applicationName"];

            if (string.IsNullOrEmpty(_applicationName))
            {
                _applicationName = "/";
            }
            config.Remove("applicationName");


            #region "Initialize UseStoredProcedure"
            string storedProcedure  = config["useStoredProcedure"];
           	if (string.IsNullOrEmpty(storedProcedure))
            {
                throw new ProviderException("Empty or missing useStoredProcedure");
            }
            this._useStoredProcedure = Convert.ToBoolean(config["useStoredProcedure"]);
            config.Remove("useStoredProcedure");
            #endregion

			#region ConnectionString

			// Initialize _connectionString
			_connectionString = config["connectionString"];
			config.Remove("connectionString");

			string connect = config["connectionStringName"];
			config.Remove("connectionStringName");

			if ( String.IsNullOrEmpty(_connectionString) )
			{
				if ( String.IsNullOrEmpty(connect) )
				{
					throw new ProviderException("Empty or missing connectionStringName");
				}

				if ( DataRepository.ConnectionStrings[connect] == null )
				{
					throw new ProviderException("Missing connection string");
				}

				_connectionString = DataRepository.ConnectionStrings[connect].ConnectionString;
			}

            if ( String.IsNullOrEmpty(_connectionString) )
            {
                throw new ProviderException("Empty connection string");
			}

			#endregion
            
             #region "_providerInvariantName"

            // initialize _providerInvariantName
            this._providerInvariantName = config["providerInvariantName"];

            if (String.IsNullOrEmpty(_providerInvariantName))
            {
                throw new ProviderException("Empty or missing providerInvariantName");
            }
            config.Remove("providerInvariantName");

            #endregion

        }
		
		/// <summary>
		/// Creates a new <c cref="TransactionManager"/> instance from the current datasource.
		/// </summary>
		/// <returns></returns>
		public override TransactionManager CreateTransaction()
		{
			return new TransactionManager(this._connectionString);
		}
		
		/// <summary>
		/// Gets a value indicating whether to use stored procedure or not.
		/// </summary>
		/// <value>
		/// 	<c>true</c> if this repository use stored procedures; otherwise, <c>false</c>.
		/// </value>
		public bool UseStoredProcedure
		{
			get {return this._useStoredProcedure;}
			set {this._useStoredProcedure = value;}
		}
		
		 /// <summary>
        /// Gets or sets the connection string.
        /// </summary>
        /// <value>The connection string.</value>
		public string ConnectionString
		{
			get {return this._connectionString;}
			set {this._connectionString = value;}
		}
		
		/// <summary>
	    /// Gets or sets the invariant provider name listed in the DbProviderFactories machine.config section.
	    /// </summary>
	    /// <value>The name of the provider invariant.</value>
	    public string ProviderInvariantName
	    {
	        get { return this._providerInvariantName; }
	        set { this._providerInvariantName = value; }
	    }		
		
		///<summary>
		/// Indicates if the current <c cref="NetTiersProvider"/> implementation supports Transacton.
		///</summary>
		public override bool IsTransactionSupported
		{
			get
			{
				return true;
			}
		}

		
		#region "PurchaseProvider"
			
		private SqlPurchaseProvider innerSqlPurchaseProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="Purchase"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override PurchaseProviderBase PurchaseProvider
		{
			get
			{
				if (innerSqlPurchaseProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlPurchaseProvider == null)
						{
							this.innerSqlPurchaseProvider = new SqlPurchaseProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlPurchaseProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlPurchaseProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlPurchaseProvider SqlPurchaseProvider
		{
			get {return PurchaseProvider as SqlPurchaseProvider;}
		}
		
		#endregion
		
		
		#region "PriceProvider"
			
		private SqlPriceProvider innerSqlPriceProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="Price"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override PriceProviderBase PriceProvider
		{
			get
			{
				if (innerSqlPriceProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlPriceProvider == null)
						{
							this.innerSqlPriceProvider = new SqlPriceProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlPriceProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlPriceProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlPriceProvider SqlPriceProvider
		{
			get {return PriceProvider as SqlPriceProvider;}
		}
		
		#endregion
		
		
		#region "PreviousPurchaseProvider"
			
		private SqlPreviousPurchaseProvider innerSqlPreviousPurchaseProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="PreviousPurchase"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override PreviousPurchaseProviderBase PreviousPurchaseProvider
		{
			get
			{
				if (innerSqlPreviousPurchaseProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlPreviousPurchaseProvider == null)
						{
							this.innerSqlPreviousPurchaseProvider = new SqlPreviousPurchaseProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlPreviousPurchaseProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlPreviousPurchaseProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlPreviousPurchaseProvider SqlPreviousPurchaseProvider
		{
			get {return PreviousPurchaseProvider as SqlPreviousPurchaseProvider;}
		}
		
		#endregion
		
		
		#region "ImportProvider"
			
		private SqlImportProvider innerSqlImportProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="Import"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override ImportProviderBase ImportProvider
		{
			get
			{
				if (innerSqlImportProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlImportProvider == null)
						{
							this.innerSqlImportProvider = new SqlImportProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlImportProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlImportProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlImportProvider SqlImportProvider
		{
			get {return ImportProvider as SqlImportProvider;}
		}
		
		#endregion
		
		
		#region "AccessoryImportProvider"
			
		private SqlAccessoryImportProvider innerSqlAccessoryImportProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="AccessoryImport"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override AccessoryImportProviderBase AccessoryImportProvider
		{
			get
			{
				if (innerSqlAccessoryImportProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlAccessoryImportProvider == null)
						{
							this.innerSqlAccessoryImportProvider = new SqlAccessoryImportProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlAccessoryImportProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlAccessoryImportProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlAccessoryImportProvider SqlAccessoryImportProvider
		{
			get {return AccessoryImportProvider as SqlAccessoryImportProvider;}
		}
		
		#endregion
		
		
		#region "ProductProvider"
			
		private SqlProductProvider innerSqlProductProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="Product"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override ProductProviderBase ProductProvider
		{
			get
			{
				if (innerSqlProductProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlProductProvider == null)
						{
							this.innerSqlProductProvider = new SqlProductProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlProductProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlProductProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlProductProvider SqlProductProvider
		{
			get {return ProductProvider as SqlProductProvider;}
		}
		
		#endregion
		
		
		#region "ProductGroupProvider"
			
		private SqlProductGroupProvider innerSqlProductGroupProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="ProductGroup"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override ProductGroupProviderBase ProductGroupProvider
		{
			get
			{
				if (innerSqlProductGroupProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlProductGroupProvider == null)
						{
							this.innerSqlProductGroupProvider = new SqlProductGroupProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlProductGroupProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlProductGroupProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlProductGroupProvider SqlProductGroupProvider
		{
			get {return ProductGroupProvider as SqlProductGroupProvider;}
		}
		
		#endregion
		
		
		#region "RepositoryProvider"
			
		private SqlRepositoryProvider innerSqlRepositoryProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="Repository"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override RepositoryProviderBase RepositoryProvider
		{
			get
			{
				if (innerSqlRepositoryProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlRepositoryProvider == null)
						{
							this.innerSqlRepositoryProvider = new SqlRepositoryProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlRepositoryProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlRepositoryProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlRepositoryProvider SqlRepositoryProvider
		{
			get {return RepositoryProvider as SqlRepositoryProvider;}
		}
		
		#endregion
		
		
		#region "PaymentDetailProvider"
			
		private SqlPaymentDetailProvider innerSqlPaymentDetailProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="PaymentDetail"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override PaymentDetailProviderBase PaymentDetailProvider
		{
			get
			{
				if (innerSqlPaymentDetailProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlPaymentDetailProvider == null)
						{
							this.innerSqlPaymentDetailProvider = new SqlPaymentDetailProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlPaymentDetailProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlPaymentDetailProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlPaymentDetailProvider SqlPaymentDetailProvider
		{
			get {return PaymentDetailProvider as SqlPaymentDetailProvider;}
		}
		
		#endregion
		
		
		#region "PurchaseDetailProvider"
			
		private SqlPurchaseDetailProvider innerSqlPurchaseDetailProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="PurchaseDetail"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override PurchaseDetailProviderBase PurchaseDetailProvider
		{
			get
			{
				if (innerSqlPurchaseDetailProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlPurchaseDetailProvider == null)
						{
							this.innerSqlPurchaseDetailProvider = new SqlPurchaseDetailProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlPurchaseDetailProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlPurchaseDetailProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlPurchaseDetailProvider SqlPurchaseDetailProvider
		{
			get {return PurchaseDetailProvider as SqlPurchaseDetailProvider;}
		}
		
		#endregion
		
		
		#region "StoredProductProvider"
			
		private SqlStoredProductProvider innerSqlStoredProductProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="StoredProduct"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override StoredProductProviderBase StoredProductProvider
		{
			get
			{
				if (innerSqlStoredProductProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlStoredProductProvider == null)
						{
							this.innerSqlStoredProductProvider = new SqlStoredProductProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlStoredProductProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlStoredProductProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlStoredProductProvider SqlStoredProductProvider
		{
			get {return StoredProductProvider as SqlStoredProductProvider;}
		}
		
		#endregion
		
		
		#region "UserProvider"
			
		private SqlUserProvider innerSqlUserProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="User"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override UserProviderBase UserProvider
		{
			get
			{
				if (innerSqlUserProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlUserProvider == null)
						{
							this.innerSqlUserProvider = new SqlUserProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlUserProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlUserProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlUserProvider SqlUserProvider
		{
			get {return UserProvider as SqlUserProvider;}
		}
		
		#endregion
		
		
		#region "PaymentProvider"
			
		private SqlPaymentProvider innerSqlPaymentProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="Payment"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override PaymentProviderBase PaymentProvider
		{
			get
			{
				if (innerSqlPaymentProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlPaymentProvider == null)
						{
							this.innerSqlPaymentProvider = new SqlPaymentProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlPaymentProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlPaymentProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlPaymentProvider SqlPaymentProvider
		{
			get {return PaymentProvider as SqlPaymentProvider;}
		}
		
		#endregion
		
		
		#region "BackupPurchaseProvider"
			
		private SqlBackupPurchaseProvider innerSqlBackupPurchaseProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="BackupPurchase"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override BackupPurchaseProviderBase BackupPurchaseProvider
		{
			get
			{
				if (innerSqlBackupPurchaseProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlBackupPurchaseProvider == null)
						{
							this.innerSqlBackupPurchaseProvider = new SqlBackupPurchaseProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlBackupPurchaseProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlBackupPurchaseProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlBackupPurchaseProvider SqlBackupPurchaseProvider
		{
			get {return BackupPurchaseProvider as SqlBackupPurchaseProvider;}
		}
		
		#endregion
		
		
		#region "ImportDetailProvider"
			
		private SqlImportDetailProvider innerSqlImportDetailProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="ImportDetail"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override ImportDetailProviderBase ImportDetailProvider
		{
			get
			{
				if (innerSqlImportDetailProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlImportDetailProvider == null)
						{
							this.innerSqlImportDetailProvider = new SqlImportDetailProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlImportDetailProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlImportDetailProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlImportDetailProvider SqlImportDetailProvider
		{
			get {return ImportDetailProvider as SqlImportDetailProvider;}
		}
		
		#endregion
		
		
		#region "AccImportDetailProvider"
			
		private SqlAccImportDetailProvider innerSqlAccImportDetailProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="AccImportDetail"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override AccImportDetailProviderBase AccImportDetailProvider
		{
			get
			{
				if (innerSqlAccImportDetailProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlAccImportDetailProvider == null)
						{
							this.innerSqlAccImportDetailProvider = new SqlAccImportDetailProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlAccImportDetailProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlAccImportDetailProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlAccImportDetailProvider SqlAccImportDetailProvider
		{
			get {return AccImportDetailProvider as SqlAccImportDetailProvider;}
		}
		
		#endregion
		
		
		#region "BackupPurchaseDetailProvider"
			
		private SqlBackupPurchaseDetailProvider innerSqlBackupPurchaseDetailProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="BackupPurchaseDetail"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override BackupPurchaseDetailProviderBase BackupPurchaseDetailProvider
		{
			get
			{
				if (innerSqlBackupPurchaseDetailProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlBackupPurchaseDetailProvider == null)
						{
							this.innerSqlBackupPurchaseDetailProvider = new SqlBackupPurchaseDetailProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlBackupPurchaseDetailProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlBackupPurchaseDetailProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlBackupPurchaseDetailProvider SqlBackupPurchaseDetailProvider
		{
			get {return BackupPurchaseDetailProvider as SqlBackupPurchaseDetailProvider;}
		}
		
		#endregion
		
		
		#region "CustomerProvider"
			
		private SqlCustomerProvider innerSqlCustomerProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="Customer"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override CustomerProviderBase CustomerProvider
		{
			get
			{
				if (innerSqlCustomerProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlCustomerProvider == null)
						{
							this.innerSqlCustomerProvider = new SqlCustomerProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlCustomerProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlCustomerProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlCustomerProvider SqlCustomerProvider
		{
			get {return CustomerProvider as SqlCustomerProvider;}
		}
		
		#endregion
		
		
		#region "ExportProvider"
			
		private SqlExportProvider innerSqlExportProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="Export"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override ExportProviderBase ExportProvider
		{
			get
			{
				if (innerSqlExportProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlExportProvider == null)
						{
							this.innerSqlExportProvider = new SqlExportProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlExportProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlExportProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlExportProvider SqlExportProvider
		{
			get {return ExportProvider as SqlExportProvider;}
		}
		
		#endregion
		
		
		#region "GuaranteeListProvider"
			
		private SqlGuaranteeListProvider innerSqlGuaranteeListProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="GuaranteeList"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override GuaranteeListProviderBase GuaranteeListProvider
		{
			get
			{
				if (innerSqlGuaranteeListProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlGuaranteeListProvider == null)
						{
							this.innerSqlGuaranteeListProvider = new SqlGuaranteeListProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlGuaranteeListProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlGuaranteeListProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlGuaranteeListProvider SqlGuaranteeListProvider
		{
			get {return GuaranteeListProvider as SqlGuaranteeListProvider;}
		}
		
		#endregion
		
		
		#region "ExportDetailProvider"
			
		private SqlExportDetailProvider innerSqlExportDetailProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="ExportDetail"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override ExportDetailProviderBase ExportDetailProvider
		{
			get
			{
				if (innerSqlExportDetailProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlExportDetailProvider == null)
						{
							this.innerSqlExportDetailProvider = new SqlExportDetailProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlExportDetailProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlExportDetailProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlExportDetailProvider SqlExportDetailProvider
		{
			get {return ExportDetailProvider as SqlExportDetailProvider;}
		}
		
		#endregion
		
		
		#region "GuaranteeProvider"
			
		private SqlGuaranteeProvider innerSqlGuaranteeProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="Guarantee"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override GuaranteeProviderBase GuaranteeProvider
		{
			get
			{
				if (innerSqlGuaranteeProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlGuaranteeProvider == null)
						{
							this.innerSqlGuaranteeProvider = new SqlGuaranteeProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlGuaranteeProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlGuaranteeProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlGuaranteeProvider SqlGuaranteeProvider
		{
			get {return GuaranteeProvider as SqlGuaranteeProvider;}
		}
		
		#endregion
		
		
		#region "FunctionProvider"
			
		private SqlFunctionProvider innerSqlFunctionProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="Function"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override FunctionProviderBase FunctionProvider
		{
			get
			{
				if (innerSqlFunctionProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlFunctionProvider == null)
						{
							this.innerSqlFunctionProvider = new SqlFunctionProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlFunctionProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlFunctionProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlFunctionProvider SqlFunctionProvider
		{
			get {return FunctionProvider as SqlFunctionProvider;}
		}
		
		#endregion
		
		
		#region "UserFunctionProvider"
			
		private SqlUserFunctionProvider innerSqlUserFunctionProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="UserFunction"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override UserFunctionProviderBase UserFunctionProvider
		{
			get
			{
				if (innerSqlUserFunctionProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlUserFunctionProvider == null)
						{
							this.innerSqlUserFunctionProvider = new SqlUserFunctionProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlUserFunctionProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlUserFunctionProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlUserFunctionProvider SqlUserFunctionProvider
		{
			get {return UserFunctionProvider as SqlUserFunctionProvider;}
		}
		
		#endregion
		
		
		
		#region "General data access methods"

		#region "ExecuteNonQuery"
		/// <summary>
		/// Executes the non query.
		/// </summary>
		/// <param name="storedProcedureName">Name of the stored procedure.</param>
		/// <param name="parameterValues">The parameter values.</param>
		/// <returns></returns>
		public override int ExecuteNonQuery(string storedProcedureName, params object[] parameterValues)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);
			return database.ExecuteNonQuery(storedProcedureName, parameterValues);	
		}

		/// <summary>
		/// Executes the non query.
		/// </summary>
		/// <param name="transactionManager">The transaction manager.</param>
		/// <param name="storedProcedureName">Name of the stored procedure.</param>
		/// <param name="parameterValues">The parameter values.</param>
		/// <returns></returns>
		public override int ExecuteNonQuery(TransactionManager transactionManager, string storedProcedureName, params object[] parameterValues)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);
			return database.ExecuteNonQuery(transactionManager.TransactionObject, storedProcedureName, parameterValues);	
		}

		/// <summary>
		/// Executes the non query.
		/// </summary>
		/// <param name="commandWrapper">The command wrapper.</param>
		public override void ExecuteNonQuery(DbCommand commandWrapper)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);
			database.ExecuteNonQuery(commandWrapper);	
			
		}

		/// <summary>
		/// Executes the non query.
		/// </summary>
		/// <param name="transactionManager">The transaction manager.</param>
		/// <param name="commandWrapper">The command wrapper.</param>
		public override void ExecuteNonQuery(TransactionManager transactionManager, DbCommand commandWrapper)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);
			database.ExecuteNonQuery(commandWrapper, transactionManager.TransactionObject);	
		}


		/// <summary>
		/// Executes the non query.
		/// </summary>
		/// <param name="commandType">Type of the command.</param>
		/// <param name="commandText">The command text.</param>
		/// <returns></returns>
		public override int ExecuteNonQuery(CommandType commandType, string commandText)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);
			return database.ExecuteNonQuery(commandType, commandText);	
		}
		/// <summary>
		/// Executes the non query.
		/// </summary>
		/// <param name="transactionManager">The transaction manager.</param>
		/// <param name="commandType">Type of the command.</param>
		/// <param name="commandText">The command text.</param>
		/// <returns></returns>
		public override int ExecuteNonQuery(TransactionManager transactionManager, CommandType commandType, string commandText)
		{
			Database database = transactionManager.Database;			
			return database.ExecuteNonQuery(transactionManager.TransactionObject , commandType, commandText);				
		}
		#endregion

		#region "ExecuteDataReader"
		/// <summary>
		/// Executes the reader.
		/// </summary>
		/// <param name="storedProcedureName">Name of the stored procedure.</param>
		/// <param name="parameterValues">The parameter values.</param>
		/// <returns></returns>
		public override IDataReader ExecuteReader(string storedProcedureName, params object[] parameterValues)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);			
			return database.ExecuteReader(storedProcedureName, parameterValues);	
		}

		/// <summary>
		/// Executes the reader.
		/// </summary>
		/// <param name="transactionManager">The transaction manager.</param>
		/// <param name="storedProcedureName">Name of the stored procedure.</param>
		/// <param name="parameterValues">The parameter values.</param>
		/// <returns></returns>
		public override IDataReader ExecuteReader(TransactionManager transactionManager, string storedProcedureName, params object[] parameterValues)
		{
			Database database = transactionManager.Database;
			return database.ExecuteReader(transactionManager.TransactionObject, storedProcedureName, parameterValues);	
		}

		/// <summary>
		/// Executes the reader.
		/// </summary>
		/// <param name="commandWrapper">The command wrapper.</param>
		/// <returns></returns>
		public override IDataReader ExecuteReader(DbCommand commandWrapper)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);			
			return database.ExecuteReader(commandWrapper);	
		}

		/// <summary>
		/// Executes the reader.
		/// </summary>
		/// <param name="transactionManager">The transaction manager.</param>
		/// <param name="commandWrapper">The command wrapper.</param>
		/// <returns></returns>
		public override IDataReader ExecuteReader(TransactionManager transactionManager, DbCommand commandWrapper)
		{
			Database database = transactionManager.Database;
			return database.ExecuteReader(commandWrapper, transactionManager.TransactionObject);	
		}


		/// <summary>
		/// Executes the reader.
		/// </summary>
		/// <param name="commandType">Type of the command.</param>
		/// <param name="commandText">The command text.</param>
		/// <returns></returns>
		public override IDataReader ExecuteReader(CommandType commandType, string commandText)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);
			return database.ExecuteReader(commandType, commandText);	
		}
		/// <summary>
		/// Executes the reader.
		/// </summary>
		/// <param name="transactionManager">The transaction manager.</param>
		/// <param name="commandType">Type of the command.</param>
		/// <param name="commandText">The command text.</param>
		/// <returns></returns>
		public override IDataReader ExecuteReader(TransactionManager transactionManager, CommandType commandType, string commandText)
		{
			Database database = transactionManager.Database;			
			return database.ExecuteReader(transactionManager.TransactionObject , commandType, commandText);				
		}
		#endregion

		#region "ExecuteDataSet"
		/// <summary>
		/// Executes the data set.
		/// </summary>
		/// <param name="storedProcedureName">Name of the stored procedure.</param>
		/// <param name="parameterValues">The parameter values.</param>
		/// <returns></returns>
		public override DataSet ExecuteDataSet(string storedProcedureName, params object[] parameterValues)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);			
			return database.ExecuteDataSet(storedProcedureName, parameterValues);	
		}

		/// <summary>
		/// Executes the data set.
		/// </summary>
		/// <param name="transactionManager">The transaction manager.</param>
		/// <param name="storedProcedureName">Name of the stored procedure.</param>
		/// <param name="parameterValues">The parameter values.</param>
		/// <returns></returns>
		public override DataSet ExecuteDataSet(TransactionManager transactionManager, string storedProcedureName, params object[] parameterValues)
		{
			Database database = transactionManager.Database;
			return database.ExecuteDataSet(transactionManager.TransactionObject, storedProcedureName, parameterValues);	
		}

		/// <summary>
		/// Executes the data set.
		/// </summary>
		/// <param name="commandWrapper">The command wrapper.</param>
		/// <returns></returns>
		public override DataSet ExecuteDataSet(DbCommand commandWrapper)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);			
			return database.ExecuteDataSet(commandWrapper);	
		}

		/// <summary>
		/// Executes the data set.
		/// </summary>
		/// <param name="transactionManager">The transaction manager.</param>
		/// <param name="commandWrapper">The command wrapper.</param>
		/// <returns></returns>
		public override DataSet ExecuteDataSet(TransactionManager transactionManager, DbCommand commandWrapper)
		{
			Database database = transactionManager.Database;
			return database.ExecuteDataSet(commandWrapper, transactionManager.TransactionObject);	
		}


		/// <summary>
		/// Executes the data set.
		/// </summary>
		/// <param name="commandType">Type of the command.</param>
		/// <param name="commandText">The command text.</param>
		/// <returns></returns>
		public override DataSet ExecuteDataSet(CommandType commandType, string commandText)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);
			return database.ExecuteDataSet(commandType, commandText);	
		}
		/// <summary>
		/// Executes the data set.
		/// </summary>
		/// <param name="transactionManager">The transaction manager.</param>
		/// <param name="commandType">Type of the command.</param>
		/// <param name="commandText">The command text.</param>
		/// <returns></returns>
		public override DataSet ExecuteDataSet(TransactionManager transactionManager, CommandType commandType, string commandText)
		{
			Database database = transactionManager.Database;			
			return database.ExecuteDataSet(transactionManager.TransactionObject , commandType, commandText);				
		}
		#endregion

		#region "ExecuteScalar"
		/// <summary>
		/// Executes the scalar.
		/// </summary>
		/// <param name="storedProcedureName">Name of the stored procedure.</param>
		/// <param name="parameterValues">The parameter values.</param>
		/// <returns></returns>
		public override object ExecuteScalar(string storedProcedureName, params object[] parameterValues)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);			
			return database.ExecuteScalar(storedProcedureName, parameterValues);	
		}

		/// <summary>
		/// Executes the scalar.
		/// </summary>
		/// <param name="transactionManager">The transaction manager.</param>
		/// <param name="storedProcedureName">Name of the stored procedure.</param>
		/// <param name="parameterValues">The parameter values.</param>
		/// <returns></returns>
		public override object ExecuteScalar(TransactionManager transactionManager, string storedProcedureName, params object[] parameterValues)
		{
			Database database = transactionManager.Database;
			return database.ExecuteScalar(transactionManager.TransactionObject, storedProcedureName, parameterValues);	
		}

		/// <summary>
		/// Executes the scalar.
		/// </summary>
		/// <param name="commandWrapper">The command wrapper.</param>
		/// <returns></returns>
		public override object ExecuteScalar(DbCommand commandWrapper)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);			
			return database.ExecuteScalar(commandWrapper);	
		}

		/// <summary>
		/// Executes the scalar.
		/// </summary>
		/// <param name="transactionManager">The transaction manager.</param>
		/// <param name="commandWrapper">The command wrapper.</param>
		/// <returns></returns>
		public override object ExecuteScalar(TransactionManager transactionManager, DbCommand commandWrapper)
		{
			Database database = transactionManager.Database;
			return database.ExecuteScalar(commandWrapper, transactionManager.TransactionObject);	
		}

		/// <summary>
		/// Executes the scalar.
		/// </summary>
		/// <param name="commandType">Type of the command.</param>
		/// <param name="commandText">The command text.</param>
		/// <returns></returns>
		public override object ExecuteScalar(CommandType commandType, string commandText)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);
			return database.ExecuteScalar(commandType, commandText);	
		}
		/// <summary>
		/// Executes the scalar.
		/// </summary>
		/// <param name="transactionManager">The transaction manager.</param>
		/// <param name="commandType">Type of the command.</param>
		/// <param name="commandText">The command text.</param>
		/// <returns></returns>
		public override object ExecuteScalar(TransactionManager transactionManager, CommandType commandType, string commandText)
		{
			Database database = transactionManager.Database;			
			return database.ExecuteScalar(transactionManager.TransactionObject , commandType, commandText);				
		}
		#endregion

		#endregion


	}
}
